#include "pokemon.h"
#include"GlobalObject.h"
#include <QRandomGenerator>
#include <algorithm>

// 元素相克计算实现
float getElementEffectiveness(Element attacker, Element defender)
{
    switch (attacker) {
    case Element::None:
        return (defender == Element::Rock || defender == Element::Steel) ? 0.5f : 1.0f;
    case Element::Water:
        return (defender == Element::Fire || defender == Element::Rock)     ? 1.5f
               : (defender == Element::Grass || defender == Element::Water) ? 0.5f
                                                                            : 1.0f;
    case Element::Grass:
        return (defender == Element::Water || defender == Element::Rock) ? 1.5f
               : (defender == Element::Fire || defender == Element::Poison
                  || defender == Element::Steel || defender == Element::Grass)
                   ? 0.5f
                   : 1.0f;
    case Element::Fire:
        return (defender == Element::Grass || defender == Element::Steel || defender == Element::Ice)
                   ? 1.5f
               : (defender == Element::Water || defender == Element::Rock
                  || defender == Element::Fire)
                   ? 0.5f
                   : 1.0f;
    case Element::Steel:
        return (defender == Element::Ice || defender == Element::Rock) ? 1.5f
               : (defender == Element::Fire || defender == Element::Electric
                  || defender == Element::Steel || defender == Element::Water)
                   ? 0.5f
                   : 1.0f;
    case Element::Rock:
        return (defender == Element::Fire || defender == Element::Ice) ? 1.5f
               : (defender == Element::Steel)                          ? 0.5f
                                                                       : 1.0f;
    case Element::Electric:
        return (defender == Element::Water)                                    ? 1.5f
               : (defender == Element::Grass || defender == Element::Electric) ? 0.5f
                                                                               : 1.0f;
    case Element::Ice:
        return (defender == Element::Grass) ? 1.5f
               : (defender == Element::Water || defender == Element::Fire
                  || defender == Element::Steel || defender == Element::Ice)
                   ? 0.5f
                   : 1.0f;
    case Element::Poison:
        return (defender == Element::Water || defender == Element::Grass) ? 1.5f
               : (defender == Element::Steel || defender == Element::Rock
                  || defender == Element::Poison)
                   ? 0.5f
                   : 1.0f;
    default:
        return 1.0f;
    }
}

// Skill类实现
Skill::Skill(QString name, int power, Element element, QString soundPath, SkillType type)
    : m_name(name)
    , m_power(power)
    , m_element(element)
    , m_type(type)
    , soundPath(soundPath)
{}

int Skill::calculateDamage(Pokemon *user, Pokemon *target)
{
    float modifier = getElementEffectiveness(m_element, target->getElement());
    double AtoD = (user->getattack()*1.0) / (target->getdefense()*1.0);
    double variance = (QRandomGenerator::global()->bounded(85, 101)) / 100.0;

    return std::max(1, static_cast<int>(variance * AtoD * m_power * modifier));
}

//回复技能
HealSkill::HealSkill(
    QString name, int basePower, bool scalesWithAttack, bool scalesWithMaxHP, float hpPercentage)
    : Skill(name, basePower, Element::None, "", SkillType::Heal)
    , m_scalesWithAttack(scalesWithAttack)
    , m_scalesWithMaxHP(scalesWithMaxHP)
    , m_hpPercentage(hpPercentage)
{}

int HealSkill::calculateDamage(Pokemon *user, Pokemon * /*target*/)
{
    int healAmount = getPower(); // 基础回复量

    // 1. 攻击力加成（物理型回复）
    if (m_scalesWithAttack) {
        healAmount += static_cast<int>(user->getattack() * 0.4); // 30%攻击力加成
    }

    // 2. 最大HP百分比加成（生命型回复）
    if (m_scalesWithMaxHP) {
        int hpBasedHeal = static_cast<int>(user->getMaxHP() * m_hpPercentage);
        healAmount += qMax(healAmount, hpBasedHeal); // 取两者中较大值
    }

    // 确保回复量不超过最大HP
    int maxPossible = user->getMaxHP() - user->getHP();
    return qMin(healAmount, maxPossible);
}

void Skill::use(Pokemon *user, Pokemon *target)
{
    int effectValue = calculateDamage(user, target);
    damage=effectValue;

    // 应用主要效果
    if (m_type == SkillType::Damage) {
        target->takeDamage(effectValue);
        emit skillUsed(QString("%1 使用了 %2，造成 %3 点伤害！")
                           .arg(user->getName())
                           .arg(m_name)
                           .arg(effectValue));
    } else if (m_type == SkillType::Heal) {
        user->heal(effectValue);
        emit skillUsed(QString("%1 使用了 %2，回复了 %3 点HP！")
                           .arg(user->getName())
                           .arg(m_name)
                           .arg(effectValue));
    }
}

// Pokemon类实现
Pokemon::Pokemon(QString name, int hp, int attack, int defense, Element element, QString imagePath)
    : m_name(name)
    , m_hp(hp)
    , m_maxHP(hp)
    , m_attack(attack)
    , m_defense(defense)
    , m_element(element)
    , m_image(imagePath)
{}

void Pokemon::addSkill(Skill *skill)
{
    if (m_skills.size() < 4)
        m_skills.append(skill);
}

void Pokemon::takeDamage(int damage) //伤害
{
    m_hp = std::max(0, m_hp - damage);
    emit hpChanged(m_hp, m_maxHP);
    if (m_hp <= 0)
        emit fainted();
}

void Pokemon::heal(int amount) //回复
{
    if (amount <= 0)
        return;

    int newHP = qMin(m_hp + amount, m_maxHP);
    int actualHeal = newHP - m_hp;

    if (actualHeal > 0) {
        m_hp = newHP;
        emit hpChanged(m_hp, m_maxHP);
        emit healed(actualHeal); // 发送具体回复量
    }
}

void Pokemon::useSkill(int index, Pokemon *target)
{
    if (index < m_skills.size())
        m_skills[index]->use(this, target);
    emit skillused(index, this);
}
